const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const commonConfig = require('./webpack.common')(false);
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const path = require('path');
// const { ReactLoadablePlugin } = require('react-loadable/webpack');
const CompressionPlugin = require('compression-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const apiPrefix = '/yyrapi';
const commitHash = require('child_process').execSync('git rev-parse HEAD').toString().trim();


const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';

// 自定义插件，生成一个js文件，内容就是git commit的值
class VersionPlugin {
  apply(compiler) {
    // emit 是异步 hook，使用 tapAsync 触及它，还可以使用 tapPromise/tap(同步)
    compiler.hooks.emit.tapAsync('FileListPlugin', (compilation, callback) => {
      // 将这个列表作为一个新的文件资源，插入到 webpack 构建中：
      const text = `window.git_commit = '${commitHash}';`;
      // eslint-disable-next-line
      compilation.assets['version_file.js'] = {
        source: () => {
          return text;
        },
        size: () => {
          return text.length;
        },
      };
      callback();
    });
  }
}


const plugins = [
  new VersionPlugin(),
  new CompressionPlugin(),
  new webpack.DllReferencePlugin({
    manifest: path.join(__dirname, `../lib/manifest.${mode}.json`),
  }),
  new CopyWebpackPlugin([{
    from: path.join(__dirname, '../lib'),
    to: path.join(__dirname, '../build/lib'),
  }]),

  new CopyWebpackPlugin([{
    from: path.join(__dirname, '../assets/wx/*'),
    flatten: true,
    to: path.join(__dirname, '../build/'),
  }]),
  new MiniCssExtractPlugin({
    // Options similar to the same options in webpackOptions.output
    // both options are optional
    filename: '[name].[chunkhash].css',
    // chunkFilename: '[id].css',
  }),
  // new ReactLoadablePlugin({
  //   filename: path.join(__dirname, '../dist/client/react-loadable.json'),
  // }),
  new webpack.DefinePlugin({
    'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
    'process.env.API_PREFIX': JSON.stringify(apiPrefix),
    'process.env.OLD_H5_ENV': JSON.stringify(process.env.OLD_H5_ENV),
    'process.env.COMMIT': JSON.stringify(commitHash),
  }),
  new webpack.HashedModuleIdsPlugin(),
  new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  new HtmlWebpackPlugin({
    template: path.join(__dirname, '../assets/html/index.html'),
    filename: 'index.html',
    inject: 'body',
    titleBlock: '<%= title %>',
    scriptBlock: '<%- script %>',
    jsBlock: '<%- js %>',
    htmlBlock: '<%- html %>',
    tongjiBlock: '<%- tongji %>',
    alwaysWriteToDisk: true,
    minify: true,
    mode,
  }),
  new HtmlWebpackHarddiskPlugin(),
];

if (process.env.NODE_ENV !== 'local') {
  plugins.push(
    new CleanWebpackPlugin(['build'], {
      root: path.join(__dirname, '..'),
    }),
  );
}

if (process.env.ANALYZER) {
  plugins.push(new BundleAnalyzerPlugin());
}

const config = merge(commonConfig, {
  mode,
  entry: {
    app: [
      path.join(__dirname, '../common/core/common.js'),
      path.join(__dirname, '../client/v2/app.js'),
    ],
  },
  plugins,
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        uglifyOptions: {
          compress: {
            drop_console: true,
          },
        },
      }),
    ],
    runtimeChunk: true,
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        // 'stable-vendors': {
        //   chunks: 'initial',
        //   minChunks: 1,
        //   test: (module) => {
        //     return stableLibs.some(lib => module.context && module.context.includes(lib));
        //   },
        //   priority: 10,
        //   reuseExistingChunk: true,
        // },
        vendors: {
          minChunks: 1,
          test: /[\\/]node_modules[\\/]/,
          priority: 9,
          reuseExistingChunk: true,
        },
        common: {
          minChunks: 2,
          test: /common/,
          priority: 8,
          reuseExistingChunk: true,
        },
      },
    },
  },
  output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].js',
    path: path.join(__dirname, '../build'),
    publicPath: '/',
  },
  devServer: {
    contentBase: path.join(__dirname, '../build'),
    compress: true,
    port: 8088,
    disableHostCheck: true,
    proxy: {
      [apiPrefix]: {
        // target: 'http://10.200.58.17:50001', // dev
        target: 'http://172.16.174.187:50001', // dev
        // target: 'http://10.200.59.110:50000',
        // target: 'http://47.99.53.161:50001', // test1
        // target: 'http://116.62.186.230:50001', // open
        pathRewrite: { [`^${apiPrefix}`]: '' },
      },
    },
  },
});

module.exports = config;
